
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Serveur {

	private static String PORT = "80"; // le port d'ecoute
	public  static  Vector<Client> clients = new Vector<Client>(); // une liste de clients
	public static String couleur = "000,000,000"; // couleur du serveur qd il ecrit dans le chat
	private static final String SEPARATOR_PROTOCOL = ":";

	public static synchronized void insererJoueur(Client client) {
		clients.add(client);
	}
	
	/**
	 * Donne une couleur aleatoire
	 * @return String une couleur sous la forme xxx,yyy,zzz dans le code RGB
	 */
	public static String getRandomStringColor(){
		Random r = new Random();
		return ""+r.nextInt(255)+","+r.nextInt(255)+","+r.nextInt(255);
	}
	
	/**
	 * Enleve un client a la liste des clients
	 * @param client
	 */
	public synchronized void retirerClient(Client client) {
		clients.remove(client);
	}
	/**
	 * Un broadcast pour diffuser a tous les clients
	 * @param data
	 * @param from
	 */
	@SuppressWarnings("deprecation")
	public synchronized static void envoieATous(String data, String from,String salle,String couleur) {
		Iterator<Client> client = clients.iterator();
		Date d = new Date();
		String hours = ""+d.getHours();
		String minutes = ""+d.getMinutes();
		if(hours.length() < 2){
			hours = "0"+hours;
		}
		if(minutes.length() < 2){
			minutes = "0"+minutes;
		}
		while (client.hasNext()) {
			Client joueur = client.next();
			try {
				Protocol.snd_chat(joueur.pw,"("+hours+":"+minutes+") ", data, from,salle,couleur);
			} catch (ProtocolException e) {
				e.printStackTrace();
			}
		}
	}
	/**
	 * Le serveur met a jour la liste des joueurs de la salle(qd qlq un se connecte ou se deconnecte)
	 * @param clients
	 * @param monClient
	 */
	public static void updateConnectedJoueurs(Client monClient){
		
		try {
			Protocol.snd_joueur(monClient.pw, monClient.name, "connected",monClient.couleur);
		} catch (ProtocolException e1) {
			e1.printStackTrace();
		}
		
		// MAJ de la liste des joueurs
		Iterator<Client> client = Serveur.clients.iterator();
		while(client.hasNext()){
			Client joueur = client.next();
			try{
				Protocol.snd_joueur(joueur.pw, monClient.name, "connected", monClient.couleur);
				Protocol.snd_joueur(monClient.pw, joueur.name, "connected", joueur.couleur);
			}catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * Fonction main de lancement du serveur
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		if(args.length > 0){
			PORT = args[0];
		}
		System.out.println("Serveur en ecoute sur le port "+PORT);
		try {
			ServerSocket service = new ServerSocket(Integer.parseInt(PORT));

			MAIN:while (true) {
				Socket connexion = service.accept();
				BufferedReader entree = new BufferedReader(new InputStreamReader(connexion.getInputStream()));
	
				HashMap<String, String> h = new HashMap<String, String>(); 
				String s;
				while((s=entree.readLine())!= null ){ 
					if (s.equals("FIN")){
						break;
					}
					try{
						Pattern pattern = Pattern.compile("^(\\w*)"+SEPARATOR_PROTOCOL+"(.*)$");
						Matcher matcher = pattern.matcher(s);
						if (matcher.find()) {
							String action = matcher.group(1);
							String values = matcher.group(2);
							h.put(action, values);
						} else {
							throw new ProtocolException("Non respect du protocol : "+s, h);
						}
					}catch(Exception e){
						System.err.println("Erreur de parsing");
						continue MAIN;
					}
				}
				if(h.get("type").equals("connect")){
					String pseudo = h.get("pseudo");
					Client monClient=new Client(connexion,pseudo, Serveur.getRandomStringColor());
					Protocol.snd_otp(monClient);
					// FIXME :: on demarre le thread meme si le rcv_otp est mauvais ...
	    			monClient.th = new ThreadServeur(connexion, pseudo, monClient);
					monClient.th.start();
				}
			}
		}
		catch (IOException e) {
			System.err.println("Erreur : " + e);
		}
	}
}
